package com.share.shareplatform.shareorder.controller;



import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.share.shareplatform.common.state.OrderState;
import com.share.shareplatform.common.state.OrderType;
import com.share.shareplatform.pojo.Goods;
import com.share.shareplatform.pojo.Order;
import com.share.shareplatform.pojo.Shop;
import com.share.shareplatform.pojo.User;
import com.share.shareplatform.pojo.exception.LogicException;
import com.share.shareplatform.shareorder.service.OrderService;
import com.share.shareplatform.shareorder.service.feign.GoodsService;
import com.share.shareplatform.shareorder.service.feign.ShopService;
import com.share.shareplatform.shareorder.service.feign.UserService;
import com.share.shareplatform.shareorder.service.impl.PayService;
import com.share.shareplatform.util.AuthorityUtil;
import com.share.shareplatform.util.Result;
import io.seata.spring.annotation.GlobalTransactional;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;


@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private UserService userService;

    @Autowired
    private PayService payService;

    @Autowired
    private ShopService shopService;
    /*
     *
     *
     * 订单添加
     * 1、检查用户id和商品id
     * 2、计算价格
     * 3、修改订单状态
     * 4、生成订单时间
     * 5、生成订单
     *
     * 非管理员还要验证用户id是否正确
     *
     * */
    @ApiOperation(value="添加",notes = "必需字段：goodsId,buyNumber,type\n可选字段：message\n额外说明：type的可取的值[租用,购买]")
    @PostMapping
    @PreAuthorize("hasAuthority('orderAdd')")
    public Result addOne(@RequestBody @Validated Order order) throws LogicException {
        if(order.getGoodsId()==null){
            throw new LogicException("请指定商品编号");
        }
        if(order.getBuyNumber()==null){
            throw new LogicException("请指定购买数量");
        }
        if(!OrderType.search(order.getType())){
            throw new LogicException("请指定订单类型");
        }
        if (!AuthorityUtil.hasAuthorityUtil("ROLE_admin")) {
            //获取用户jwt中的id
            Long userId =AuthorityUtil.getUserId();
            //指定订单的用户id
            order.setUserId(userId);
        }else{
            if(order.getUserId()==null){
                throw new LogicException("请指定用户Id");
            }
            //检验用户是否存在
            User user = Result.getResultValue(userService.findOneById(order.getUserId()),"user",User.class);
            if(user==null){
                throw new LogicException("该用户不存在，无法为该用户生成订单");
            }
        }
        Goods goods = Result.getResultValue(goodsService.findOneById(order.getGoodsId()),"goods",Goods.class);
        if(goods==null){
            throw  new LogicException("该商品不存在");
        }
        Order.setInit(order,goods);

        Long flag = orderService.addOne(order);
        if(flag==0){
            throw new LogicException("订单添加失败");
        }

        return Result.getInstance(200,"提交成功");
    }



    /*
     *
     *
     * 订单修改
     *
     *
     * */

    @ApiOperation(value="修改",notes = "必需字段：state\n额外说明：目前只能修改订单状态，订单其它信息无法修改")
    @PutMapping
    @PreAuthorize("hasAuthority('orderSuper')")
    public Result updateOne(@RequestBody @Validated Order order) throws LogicException {
        if(order.getId()==null){
            throw new LogicException("请指定订单Id");
        }

        if(!OrderState.search(order.getState())){
            throw new LogicException("不存在该种订单状态");
        }

        Order oldOrder = orderService.findOneById(order.getId());
        if(oldOrder==null){
            throw new LogicException("订单不存在");
        }
        Order.update(oldOrder,order);
        orderService.updateOne(order);
        return Result.getInstance(200,"success");
    }

    @ApiOperation(value="批量删除",notes = "其中ids为 'id-id-id' 这种类型的字符串")
    @DeleteMapping("/all/{ids}")
    @PreAuthorize("hasAuthority('orderDelete')")
    public Result deleteOneById(@PathVariable("ids") String  ids) throws LogicException {
        String[] stringIds=ids.split("-");
        ArrayList<Long> arrayList=new ArrayList<>();
        for(String id:stringIds){
            arrayList.add(Long.parseLong(id));
        }
        if (!AuthorityUtil.hasAuthorityUtil("ROLE_admin")) {
            orderService.deleteAllSafeByIds(arrayList);
        }else{
            Integer flag = orderService.deleteAllByIds(arrayList.toArray(new Long[arrayList.size()]));
            if(flag==0){
                throw new LogicException("删除失败，订单已不存在");
            }
        }

        return Result.getInstance(200,"删除成功");

    }

   /* @ApiOperation(value="批量删除",notes = "其中ids为 'id-id-id' 这种类型的字符串")
    @DeleteMapping("/all/{ids}")
    @PreAuthorize("hasAuthority('orderDelete')")
    public Result deleteAllByIds(@PathVariable("ids") String ids){

        String[] stringIds=ids.split("-");
        ArrayList<Long> arrayList=new ArrayList<>();
        for(String id:stringIds){
            arrayList.add(Long.parseLong(id));
        }
        orderService.deleteAllByIds(arrayList.toArray(new Long[arrayList.size()]));
        return Result.getInstance(200,"success");

    }*/

    @ApiOperation(value="查询，按id")
    @GetMapping("/{id}")
    @PreAuthorize("hasAuthority('orderFind')")
    public Result findOneById(@PathVariable("id") Long id) throws LogicException {
        Order order=orderService.findOneById(id);

        if(order==null)
            return Result.getInstance(505,"订单不存在");

        //要么是管理员，要么订单属于你
        if(!(AuthorityUtil.hasAuthorityUtil("ROLE_admin")|| order.getUserId() == AuthorityUtil.getUserId())){
            throw new LogicException("该订单不属于你");
        }

        return Result.getInstance(200,"success").put("order",order);
    }

    @ApiOperation(value="查询，按id")
    @GetMapping("/username/{username}")
    @PermitAll
    public Result findAllByUsername(@PathVariable String username) throws LogicException {
        User user = Result.getResultValue(userService.findOneByUsername(username),"user",User.class);
        List<Order> list = orderService.findAllByUserId(user.getId());
        StringBuilder stringBuilder=new StringBuilder();
        for(Order order:list){
            if (order.getGoodsId()!=null) {
                stringBuilder.append(order.getGoodsId()+"-");
            }
        }

        if(stringBuilder.length()!=0){
            stringBuilder.deleteCharAt(stringBuilder.length()-1);
            //一次性查询出结果
            Map<Long, Goods> map = Result.getMapResultValue(goodsService.findAllByIdAsMap(stringBuilder.toString()), Long.class, Goods.class);
            if(map!=null){
                for(Order order:list){
                    if (order.getGoodsId()!=null) {
                        order.setGoods(map.get(order.getGoodsId()));
                    }
                }
            }
        }

        return Result.getInstance(200,"success").put("list",list);
    }


    /*@ApiOperation(value="查询用户的所有订单",notes = "前提：用户已登录")
    @GetMapping("/user")
    @PreAuthorize("hasAuthority('orderFind')")
    public Result findOneByUserId(HttpServletRequest request){

        User user=(User)request.getSession().getAttribute("user");
        if(user==null){
            return Result.getInstance(505,"请先登录").put("list",null);
        }

        List<Order> list=orderService.findAllByUserId(user.getId());
        for(Order o:list){
            Goods goods=goodsService.findOneById(o.getGoodsId());
            if(goods!=null){
                o.setGoods(goods);
            }
        }
        return Result.getInstance(200,"success").put("list",list);
    }*/

    @ApiOperation(value="查询用户的某类订单，如待收货和待付款订单",
            notes = "前提：用户已登录\n样例：/user/state/待付款")
    @GetMapping("/user/state/{state}")
    @PreAuthorize("hasAuthority('orderFind')")

    public Result findAllByUserIdAndState(@PathVariable(value = "state")  String state){
        Long userId=AuthorityUtil.getUserId();

        if(!OrderState.search(state)){
            Result.getInstance(505,"没有该订单状态").put("list",null);
        }
        List<Order> list=orderService.findAllByUserIdAndState(userId,state);
        StringBuilder stringBuilder=new StringBuilder();
        for(Order order:list){
            if (order.getGoodsId()!=null) {
                stringBuilder.append(order.getGoodsId()+"-");
            }
        }

        if(stringBuilder.length()!=0){
            stringBuilder.deleteCharAt(stringBuilder.length()-1);
            //一次性查询出结果
            Map<Long, Goods> map = Result.getMapResultValue(goodsService.findAllByIdAsMap(stringBuilder.toString()), Long.class, Goods.class);
            if(map!=null){
                for(Order order:list){
                    if (order.getGoodsId()!=null) {
                        order.setGoods(map.get(order.getGoodsId()));
                    }
                }
            }
        }
        return Result.getInstance(200,"success").put("list",list);
    }

    @ApiOperation(value="查询用户的已经租出去的商品",
            notes = "前提：用户已登录\n其中id为用户id")
    @GetMapping("/user/rent")
    @PreAuthorize("hasAuthority('orderFind')")
    public Result findAllByShopId(){
        Long id = AuthorityUtil.getUserId();
        Shop shop = Result.getResultValue(shopService.findOneByUserId(id),"shop",Shop.class);
        if(shop==null){
            throw new LogicException("用户没有店铺");
        }

        List<Goods> goodsList = Result.getListResultValue(goodsService.findAllByShopId(shop.getId()), Goods.class);
        if(goodsList==null||goodsList.size()==0){
            throw new LogicException("用户没有可用租出商品");
        }
        List<Order> list = orderService.findAllByGoodsList(shop.getId(),goodsList);
        return Result.getInstance(200,"success").put("list",list);
    }


    @ApiOperation(value="查询用户的某类订单，如购买和租用",
            notes = "前提：用户已登录\n样例：/user/type/待付款")
    @GetMapping("/user/type/{type}")
    @PreAuthorize("hasAuthority('orderFind')")
    public Result findOneByUserIdAndType(@PathVariable(value = "type")  String type){
        Long userId=AuthorityUtil.getUserId();

        if(!OrderType.search(type)){
            Result.getInstance(505,"没有该订单类型").put("list",null);
        }
        List<Order> list=orderService.findAllByUserIdAndType(userId,type);
        StringBuilder stringBuilder=new StringBuilder();
        for(Order order:list){
            if (order.getGoodsId()!=null) {
                stringBuilder.append(order.getGoodsId()+"-");
            }
        }

        if(stringBuilder.length()!=0){
            stringBuilder.deleteCharAt(stringBuilder.length()-1);
            //一次性查询出结果
            Map<Long, Goods> map = Result.getMapResultValue(goodsService.findAllByIdAsMap(stringBuilder.toString()), Long.class, Goods.class);
            if(map!=null){
                for(Order order:list){
                    if (order.getGoodsId()!=null) {
                        order.setGoods(map.get(order.getGoodsId()));
                    }
                }
            }
        }
        return Result.getInstance(200,"success").put("list",list);
    }



    /*@ApiOperation(value="用户支付多个订单", notes = "前提：用户已登录")
    //付款未付款的商品
    @PutMapping("/user")
    @PreAuthorize("hasAuthority('orderFind')")
    public Result updateAllByUser(HttpServletRequest request){
        Long userId=AuthorityUtil.getUserId();;

        List<Order> list=orderService.findAllByUserId(userId);

        *//*
     * 付款逻辑
     * *//*

        for(Order o:list){
            o.setState(OrderState.WAITING_FOR_PAYMENT.getState());
            orderService.updateOne(o);
        }
        return Result.getInstance(200,"success").put("list",list);
    }*/

    @ApiOperation(value="用户支付未支付的订单", notes = "其中ids为 'id-id-id' 这种类型的字符串\n额外说明：目前只是模拟支付，只是改变订单支付状态")
    //付款单个未付款的商品
    @GetMapping("/user/pay/{ids}")
    @PreAuthorize("hasAuthority('orderFind')")
    public Result updateOneByUserAndId(@PathVariable String ids, HttpServletResponse response) throws Exception {
        String[] stringIds=ids.split("-");
        ArrayList<Long> arrayList=new ArrayList<>();
        try{
            for(String id:stringIds){
                arrayList.add(Long.parseLong(id));
            }
        }catch (Exception e){
            throw new LogicException("订单编号有误");
        }
        if(arrayList.size()==0){
            throw new LogicException("请输入正确的订单编号");
        }

        Long userId=AuthorityUtil.getUserId();

        ArrayList<Order> orderList=new ArrayList<>(arrayList.size());
        StringBuilder idBuilder=new StringBuilder();
        for(Long v:arrayList){
            Order order = orderService.findOneById(v);
            if(order==null){
                throw new LogicException("该订单不存在");
            }
            if(order.getUserId()!=userId){
                throw new LogicException("该订单不属于你");
            }
            if(!order.getState().equals(OrderState.WAITING_FOR_PAYMENT.getState())){
                throw new LogicException("部分订单已经付款,请重试");
            }
            //将商品id组合
            idBuilder.append(order.getGoodsId()+"-");
            orderList.add(order);
        }
        idBuilder.deleteCharAt(idBuilder.length()-1);
        Map<Long,Goods> map = Result.getMapResultValue(goodsService.findAllByIdAsMap(idBuilder.toString()),Long.class,Goods.class);
        for(Order o:orderList){
            Goods goods = (Goods)map.get(o.getGoodsId());
            o.setGoods(goods);
        }

        /**
         * 付款逻辑
         *
         *
         * */
        Result result = Result.getInstance(200, "请付款");
        payService.alipay(orderList,result,response);


        return result;
    }


    @GetMapping("/returnUrl")
    public Result returnUrl(HttpServletRequest request, HttpServletResponse response)
            throws IOException, AlipayApiException, LogicException {
        System.out.println("=================================同步回调=====================================");
        // 获取支付宝GET过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            // 乱码解决，这段代码在出现乱码时使用
            valueStr = new String(valueStr.getBytes("utf-8"), "utf-8");
            params.put(name, valueStr);
        }

        System.out.println(params);//查看参数都有哪些
        Result result=payService.returnUrl(params,request);

        return result;
    }

    @ApiOperation(value="用户支付未支付的订单", notes = "其中ids为 'id-id-id' 这种类型的字符串\n额外说明：目前只是模拟支付，只是改变订单支付状态")
    //付款单个未付款的商品
    @GetMapping("/test")
    @PreAuthorize("hasAuthority('orderFind')")
    public Result updateTest()  {

        ArrayList<Long> longs = new ArrayList<>();
        longs.add(35l);
        orderService.globalUpdateAllPaymentStateByIds(longs);

        return Result.getInstance(200,"success");

    }

}
